package tsing.javase.thread.pool;

import java.util.concurrent.*;

/**
 * 定义单例线程池
 *
 * 饿汉式：预加载
 * 懒汉式：延迟加载
 *
 */


/**
 *
 *
 * jdk自带的创建线程池的几种方式：
 *
 * Executors.newFixedThreadPool(nThreads)：建立一个定长线程池，可控制线程最大并发数，超出的线程会在队列中等待。
 * Executors.newCachedThreadPool()：建立一个可缓存线程池，若是线程池长度超过处理须要，可灵活回收空闲线程，若无可回收，则新建线程。
 * Executors.newSingleThreadExecutor()：建立一个单线程化的线程池，它只会用惟一的工做线程来执行任务， 保证全部任务按照指定顺序(FIFO, LIFO, 优先级)执行。
 * Executors.newScheduledThreadPool(nThreads)：建立一个定长线程池，支持定时及周期性任务执行。
 *
 *
 *创建自定义的线程池： new ThreadPoolExecutor（）
 *
 * corePoolSize（int）：线程池中保持的线程数量，包括空闲线程在内。也就是线程池释放的最小线程数量界限。
 *
 * maximumPoolSize（int）: 线程池中嫩容纳最大线程数量。
 *
 * keepAliveTime(long): 空闲线程保持在线程池中的时间，当线程池中线程数量大于 corePoolSize 的时候。
 *
 * unit(TimeUnit枚举类): 上面参数时间的单位，可以是分钟，秒，毫秒等等。
 *
 * workQueue（BlockingQueue）: 任务队列，当线程任务提交到线程池以后，首先放入队列中，然后线程池按照该任务队列依次执行相应的任务。可以使用的 workQueue 有很多，比如：LinkedBlockingQueue 等等。
 *
 * threadFactory(ThreadFactory类): 新线程产生工厂类。
 *
 * handler（RejectedExecutionHandler类）: 当提交线程拒绝执行、异常的时候，处理异常的类。该类取值如下：(注意都是内部类)
 *
 *
 *
 * 拒绝策略：
 * ThreadPoolExecutor.AbortPolicy: 丢弃任务并抛出RejectedExecutionException 异常。
 *
 * ThreadPoolExecutor.DiscardPolicy：也是丢弃任务，但是不抛出异常。
 *
 * ThreadPoolExecutor.DiscardOldestPolicy：丢弃队列最前面的任务，然后重新尝试执行任务，重复此过程。
 *
 * ThreadPoolExecutor.CallerRunsPolicy：由调用线程处理该任务。
 *
 *
 *
 *
 */


public class MyPool {


    private int corePoolSize = 10;

    private int maxnumPoolSize = 20;

    private long keepAliveTime = 3;

    private int scheduledPoolSize = 10;



    private static MyPool myPool = null;

    private ThreadPoolExecutor threadPool =null;
    private ScheduledThreadPoolExecutor scheduledPool = null;
    public ThreadPoolExecutor getThreadPool(){
        return threadPool;
    }



    public ScheduledThreadPoolExecutor getScheduledPool(){
        return scheduledPool;

    }




    private static synchronized void create(){
        if(myPool ==null){
            myPool = new MyPool();

        }
    }


    public static MyPool getInstance(){
        if(myPool == null){
            create();
        }
        return myPool;
    }


    private MyPool(){
    // 实例化线程池，这里使用的 LinkedBlockingQueue 作为 workQueue ，使用 DiscardOldestPolicy 作为 handler
        this.threadPool = new ThreadPoolExecutor(corePoolSize,maxnumPoolSize,keepAliveTime
                , TimeUnit.SECONDS,new LinkedBlockingDeque<>(10000),new ThreadPoolExecutor.CallerRunsPolicy());// 不在新线程中执行任务，而是由调用者所在的线程来执行
        //实例化计划任务线程池
        this.scheduledPool = new ScheduledThreadPoolExecutor(scheduledPoolSize);


        scheduledPool.shutdown();
        //线程池使用submit() 第一种姿势
/*        Future<?> future = scheduledPool.submit(() -> {
            System.out.println("打印");
        });*/



        //线程池使用submit() 第二种姿势
/*        try {
            Future<?> future = scheduledPool.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    return 2;
                }
            });
            Integer o =(Integer) future.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }*/


    }



}
